home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Utilities / Winter Shell 1.0d2 / Source / Libraries / KeyLib / KeyLib.c next >
Encoding:
C/C++ Source or Header  |  1994-01-09  |  5.1 KB  |  204 lines  |  [TEXT/KAHL]

  1. /* Revision History:
  2.     
  3.     93/12/24 aih
  4.     - added a function to test if a key is down
  5.     
  6.     93/03/26 AIH
  7.     - Changed KeyEdit to KeyToCmd and added checks for the help key
  8.     
  9.     92/02/20 AIH
  10.     - Added ByteLib instead of using ugly bit masks
  11.     - Added menu commands instead menu IDs and menu item numbers
  12.     
  13.     91/05/15 AIH
  14.     - Added function to test for arrow keys
  15.     
  16.     91/03/24 AIH
  17.     - Added support for international canceling
  18.     
  19.     91/03/07 AIH
  20.     - Standard command keys aren't read from a resource because it really
  21.     makes some of the code messy (can't use a switch statement on variables)
  22.     and because these keys really are standard
  23.     
  24.     91/01/05 Ari Halberstadt (AIH)
  25.     - Inserted this standard header in all files */
  26.  
  27. #include <limits.h>
  28. #include <Script.h>
  29. #include "ByteLib.h"
  30. #include "KeyLib.h"
  31.  
  32. /* return the virtual key code of the event message */
  33. unsigned char KeyVirtual(EventRecord *event)
  34. {
  35.     unsigned char key = 0;
  36.     
  37.     if (event->what == keyDown || event->what == autoKey)
  38.         key = HiByte(LoWord(event->message));
  39.     return(key);
  40. }
  41.  
  42. /* Return the equivalent standard edit command for a key down event. First,
  43.     a check is made for command key equivalents of the standard edit menu
  44.     commands, then a check is made for use of the extended keyboard function
  45.     keys. A check is also made for the clear key. The appropriate constant
  46.     corresponding to the standard edit menu item is returned, or CMD_NONE if the
  47.     key doesn't correspond to a command. */
  48. MenuCommandType KeyToCmd(EventRecord *event)
  49. {
  50.     unsigned char key = event->message;
  51.     MenuCommandType cmd = CMD_NONE;
  52.     
  53.     if (event->what == keyDown || event->what == autoKey) {
  54.         /* check for keyboard equivalents of commands */
  55.         if ((event->modifiers & cmdKey) == 0) {
  56.             switch (KeyVirtual(event)) {
  57.             case undoVFKey:    cmd = CMD_UNDO;    break;
  58.             case cutVFKey:        cmd = CMD_CUT;    break;
  59.             case copyVFKey:    cmd = CMD_COPY;    break;
  60.             case pasteVFKey:    cmd = CMD_PASTE;break;
  61.             case helpVKey:        cmd = CMD_HELP; break;
  62.             default: if (key == clearKey) cmd = CMD_CLEAR; break;
  63.             }
  64.         }
  65.         else {
  66.             switch (key) {
  67.             case undoKey:    cmd = CMD_UNDO;    break;
  68.             case cutKey:    cmd = CMD_CUT;    break;
  69.             case copyKey:    cmd = CMD_COPY;    break;
  70.             case pasteKey:    cmd = CMD_PASTE;break;
  71.             case clearKey:    cmd = CMD_CLEAR;break;
  72.             }
  73.         }
  74.     }
  75.     return(cmd);
  76. }
  77.  
  78. /* True if the event specifies a command-period combination or the escape
  79.     key. Adapted from TN#263 "International Canceling". */
  80. Boolean KeyCancel(EventRecord *event)
  81. {
  82.  
  83.     unsigned char virtual;    /* virtual key from event message */
  84.     short        code;                /* character from event message */
  85.     long        info;                /* result of KeyTrans */
  86.     long        state;            /* state for KeyTrans */
  87.     Handle    kchr;                /* the 'KCHR' resource */
  88.     Boolean    result = false;
  89.  
  90.     if (event->what == keyDown || event->what == autoKey) {
  91.  
  92.         /* get the virtual key code */
  93.         virtual = HiByte(LoWord(event->message));
  94.  
  95.         /* check for command-period */
  96.         if ((event->modifiers & cmdKey) != 0) {
  97.     
  98.             /* load the current 'KCHR' resource */
  99.             info = event->message;
  100.             kchr = GetResource('KCHR', GetScript(GetEnvirons(smKeyScript), smScriptKeys));
  101.             if (kchr && *kchr) {
  102.     
  103.                 /* build a key code for KeyTrans */
  104.                 code = ((HiByte(LoWord(event->modifiers)) & ~cmdKey) | virtual);
  105.                 state = 0;
  106.     
  107.                 /* no need to lock resource since KeyTrans won't move memory */
  108.                 info = KeyTrans(*kchr, code, &state);
  109.             }
  110.             
  111.             /* examine result */
  112.             result = (LoByte(info) == cancelKey ||
  113.                          LoByte(HiWord(info)) == cancelKey);
  114.         }
  115.         else
  116.             result = (virtual == escapeVKey);
  117.     }
  118.     return(result);
  119. }
  120.  
  121. /* true if the key is down */
  122. Boolean KeyIsDown(unsigned char key)
  123. {
  124.     KeyMap map;
  125.  
  126.     GetKeys(map);
  127.     return((((char *) map)[key / 8] & (1 << (key % 8))) != 0);
  128. }
  129.  
  130. /* true if an arrow key */
  131. Boolean KeyIsArrow(unsigned char key)
  132. {
  133.     switch(key) {
  134.     case arrowLeftKey:
  135.     case arrowRightKey:
  136.     case arrowUpKey:
  137.     case arrowDownKey:
  138.         return(true);
  139.     }
  140.     return(false);
  141. }
  142.  
  143. /* true if event specifies an arrow key */
  144. Boolean KeyArrow(EventRecord *event)
  145. {
  146.     Boolean result = false;
  147.     
  148.     if (event->what == keyDown || event->what == autoKey)
  149.         result = KeyIsArrow(event->message);
  150.     return(result);
  151. }
  152.  
  153. /* true if event specifies a movement key */
  154. Boolean KeyMovement(EventRecord *event)
  155. {
  156.     unsigned char key = event->message;
  157.     Boolean result = KeyArrow(event);
  158.     
  159.     if (! result) {
  160.         switch(KeyVirtual(event)) {
  161.         case pageUpVKey:
  162.         case pageDownVKey:
  163.         case homeVKey:
  164.         case endVKey:
  165.             result = true;
  166.             break;
  167.         }
  168.     }
  169.     return(result);
  170. }
  171.  
  172. /* true if event specifies a command key */
  173. Boolean KeyCmd(EventRecord *event)
  174. {
  175.     unsigned char key = event->message;
  176.     Boolean result = false;
  177.     
  178.     if (event->what == keyDown || event->what == autoKey) {
  179.         result = ((event->modifiers & cmdKey) != 0 || 
  180.                     KeyToCmd(event) != CMD_NONE ||
  181.                     KeyCancel(event) ||
  182.                     KeyMovement(event) ||
  183.                     key == backspaceKey);
  184.     }
  185.     return(result);
  186. }
  187.  
  188. /* true if event specifies a dialog command key */
  189. Boolean KeyCmdDlg(EventRecord *event)
  190. {
  191.     return(KeyCmd(event));
  192. }
  193.  
  194. /* true if event specifies a modal dialog command key */
  195. Boolean KeyCmdDlgModal(EventRecord *event)
  196. {
  197.     unsigned char key = event->message;
  198.     Boolean result = false;
  199.     
  200.     if (event->what == keyDown || event->what == autoKey)
  201.         result = (KeyCmdDlg(event) || key == enterKey || key == returnKey);
  202.     return(result);
  203. }
  204.